<template>
    <div class="calendar">
        <slot name="header" :date="selfTime">
            {{ selfTime }}
        </slot>
        <div class="calendar-week">
            <span class="calendar-week-item" v-for='v, k in  weeks[props.startWeek][props.weekType]'
                :key='"calendar-week-item" + k'>{{ v }}</span>
        </div>
        <div class="calendar-day">
            <nav class="calendar-day-item" :class="{ 'calendar-day-itemgray': item.status !== 1 }"
                @click="handleClick(item)" v-for="item, key in forDays" :key="'day' + key">
                <!-- :class="{ 'calendar-day-itemgray': item.status !== 1, 'calendar-day-light': item.detail ? !item.detail.isAbsence && !item.detail.isVacation && !item.detail.isHoliday : false }" -->
                <slot name="dayItem" :item="item">
                    <div class="calendar-day-item-check">
                        <template v-if="item.detail">
                            <template v-if="!item.detail.isHoliday">
                                <div class="cdic-item cdic-itemZC"
                                    v-if="item.detail ? !item.detail.isAbsence && !item.detail.isVacation : false">正常
                                </div>
                            </template>
                            <div class="cdic-item cdic-itemCD" v-if="item.detail.isLate">迟到</div>
                            <div class="cdic-item cdic-itemZT" v-if="item.detail.isEarly">早退</div>
                            <div class="cdic-item cdic-itemQQ" v-if="item.detail.isAbsence">缺勤</div>
                            <div class="cdic-item cdic-itemQJ" v-if="item.detail.isVacation">请假</div>
                            <div class="cdic-item cdic-itemXX" v-if="item.detail.isHoliday">休息</div>
                        </template>
                    </div>
                    <div class="calendar-day-item-text" :class="{ 'calendar-day-itemactive': item.active }">
                        {{ item.day }}
                    </div>
                </slot>
            </nav>
        </div>
</div>
</template>

<script setup lang="ts"  name="saCalendar">
import type { forDaysI, dayI } from './lib/interfaces';
import formatDate from '../tool/formatDate';
import { ref, defineEmits, defineExpose, defineProps, watch, reactive } from 'vue';
let emits = defineEmits(['handleClickDate']);
let count = 7 * 6;
let props = defineProps({
    'date': {
        type: Date,
        default: () => new Date()
    },
    'data': {
        type: Array,
        default: () => []
    },
    'startWeek': {
        type: Number,
        default: () => 1,
    },
    "weekType": {
        type: String,
        default: () => 'cn'
    },
    'detailkey': {
        type: String,
        default: () => 'date'
    }
});
interface weeksI {
    '1': {
        'cn': Array<String>,
        'en': Array<String>
    },
    '2': {
        'cn': Array<String>,
        'en': Array<String>
    }
}
let weeks: weeksI = reactive({
    '1': {
        'cn': ['一', '二', '三', '四', '五', '六', '日'],
        'en': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    '7': {
        'cn': ['日', '一', '二', '三', '四', '五', '六'],
        'en': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    }
});
let selfTime = ref();

let forDays = reactive<forDaysI[]>([]);

const handleClick = (item: Object) => {
    emits('handleClickDate', item);
}
const buLing = (n: number) => {
    if (n < 10) {
        return '0' + n;
    } else {
        return n;
    }
}
const isLeapYear = (year: number) => {
    if (((year % 4) == 0) && ((year % 100) != 0) || ((year % 400) == 0)) {
        return 1;
    } else {
        return 0;
    }
}

const forDaysMethods = (date: Date = new Date(), list: Object = []) => {
    let { startWeek, detailkey } = props;
    let oDate = new Date(date);
    let year = (oDate.getFullYear())                   //获取年  
    let month = (oDate.getMonth())                     //获取月
    let day = (oDate.getDate())                        //获取当日时间
    let days = ([31, 28 + isLeapYear(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]);       //所有月份的天数,这里条用的一个函数用于计算闰年
    let firstDayLeft = (new Date(year, month, 1)).getDay();
    let firstDay = (firstDayLeft == 0 ? 7 : firstDayLeft);
    selfTime.value = formatDate(date);
    let hovers: any = (list)             //父传子的参数,用于设置任务 活动悬浮效果

    let start_y = oDate.getFullYear();
    let end_y = oDate.getFullYear();
    let start_m = oDate.getMonth();
    let end_m = oDate.getMonth();

    let start = <dayI[]>([])             //用于计算 开头
    start_m -= 1;
    if (start_m < 0) {
        start_m = 11;
        start_y = start_y - 1;
    }

    let start_i_minus = 1;
    // 判断日历 周第一个是 周日 还是 周一
    if (startWeek === 1) {
        start_i_minus = 1;
    }
    if (startWeek === 7) {
        start_i_minus = 0;
    }

    if (startWeek != 7 && startWeek != 1) {
        throw new Error('startWeek只能传入1和7');//Uncaught Error: test
        return false;
    }

    for (let i = 1; i <= days[start_m]; i++) {

        if (i - start_i_minus > days[start_m] - firstDay) {
            start.push({
                status: 0,
                day: i,
                active: false,
                year: start_y,
                month: start_m,
            })
        }
    }

    let center = <dayI[]>([])             //计算中间 当前月时间
    for (let i = 1; i <= days[month]; i++) {
        let itemDay = {
            status: 1,
            day: i,
            active: false,
            year: year,
            month: month,
        }
        if (day == i) {
            itemDay.active = true
        } else {
            itemDay.active = false
        }
        center.push(itemDay)
    }

    let end = <dayI[]>([])         //计算尾部
    end_m -= 1;
    if (end_m > 11) {
        end_m = 0;
        end_y = end_y + 1;
    }
    let end_days = count - (start.length + center.length)
    for (let i = 0; i < end_days; i++) {
        end.push({
            status: 0,
            day: i + 1,
            active: false,
            year: end_y,
            month: end_m,
        })
    }
    let all = <forDaysI[]>(start.concat(center).concat(end));
    all.forEach((item: forDaysI) => {
        let dateStr = item.year + '-' + buLing(item.month + 1) + '-' + buLing(item.day);
        item['dateStr'] = dateStr;
        hovers.forEach((hover: any) => {
            if (hover[detailkey] == dateStr) {
                item['detail'] = hover;
            }
        })
    })
    forDays.length = 0;
    forDays.push(...all);
}
forDaysMethods(props.date, props.data);
watch(props, () => {
    forDaysMethods(props.date, props.data);
})
</script>

<style scoped>
.calendar {
    width: 100%;
    height: auto;
}

div {
    box-sizing: border-box;
}

.calendar-week {
    width: 100%;
    height: 45px;
    line-height: 45px;
    display: flex;
    user-select: none;
    justify-content: space-around;
    border-top: 1px solid #EDEDED;
    border-bottom: 1px solid #EDEDED;
}

.calendar-week-item {
    font-family: 'PingFang SC';
    font-style: normal;
    font-size: 14px;
    color: #999999;
}

.calendar-day {
    width: 100%;
    height: auto;
    display: flex;
    flex-wrap: wrap;
    text-align: center;
}

.calendar-day-item {
    height: 87px;
    width: 14.2857142%;
    border-right: 1px solid #EDEDED;
    border-bottom: 1px solid #EDEDED;
    padding: 8px 0px;
    box-sizing: border-box;
}

.calendar-day-item-check {
    width: 100%;
    height: 57px;
    display: flex;
    flex-direction: column;
}

/* .calendar-day-light {
    position: relative;
}

.calendar-day-light:after {
    content: '';
    display: block;
    height: 6px;
    width: 6px;
    background: #2369f5;
    position: absolute;
    bottom: 7px;
    left: 50%;
    transform: translateX(-50%);
    border-radius: 50%;
} */
.calendar-day-light+.calendar-day-light .cdic-itemZC {
    color: transparent;
    width: calc(100% + 1px);
    margin-left: -1px;
}

.cdic-item {
    height: 20px;
    line-height: 20px;
    text-align: center;
    font-family: 'PingFang SC';
    font-style: normal;
    font-weight: 600;
    font-size: 12px;
}

.cdic-itemZC {
    background-color: #ebfff7;
    color: #1ebe58;
}

.cdic-item+.cdic-item {
    margin-top: 6px;
}

.cdic-itemCD {
    background: #EFF4FF;
    color: #2369F5;
}

.cdic-itemZT {
    background: #EFFBFF;
    color: #3E89E5;
}

.cdic-itemQJ {
    background: #FFF1E8;
    color: #EE8E3C;

}

.cdic-itemQQ {
    background: #FFE8EE;
    color: #E21616;
}

.cdic-itemXX {
    background: #EFF4FF;
    color: #2369F5;
}

/* :nth-of-type选择器 very good */
.calendar-day-item:nth-of-type(7n+0) {
    border-right: none !important;
}

.calendar-day-item-hover {
    width: 100%;
    height: 10px;
    box-sizing: border-box;
    padding: 0px 10px;
    position: relative;
}

.cdih-items {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    max-height: 14px;
    width: 100%;
    overflow: hidden;
}

.cdih-item {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin: auto 0px;
    border: 2px solid #585858;
    transform: scale(.5);
}

.more {
    background: #cccc;
}

.cdih-item-show {
    position: absolute;
    display: none;
    left: 50%;
    top: 10px;
    transform: translateX(-50%);
    width: 80px;
    background: white;
    font-size: 12px;
    line-height: 20px;
    padding: 4px 12px;
    box-sizing: border-box;
    z-index: 99;
    box-shadow: 0px 0px 4px #ccc;
}

.cdih-item-show>nav {
    text-align: left;
    width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: pointer;
}

.calendar-day-item-hover:hover>.cdih-item-show {
    display: block;
}

.calendar-day-item-hover:hover .cdih-item {
    border-color: #fc8686;
}

.calendar-day-item-text {
    user-select: none;
    text-align: center;
    height: 14px;
    font-family: 'PingFang SC';
    font-style: normal;
    font-weight: 600;
    font-size: 14px;
    line-height: 14px;
    /* identical to box height, or 100% */


    color: #999999;
}

.calendar-day-itemactive {
    color: #2369f5 !important;
    font-weight: 600;
}

.calendar-day-itemgray {
    opacity: 1;
    background-color: rgba(246, 243, 243, .25);
}

.calendar-week-head {
    width: 100%;
    height: 30px;
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
    padding: 0px 10px;
}

.calendar-week-head-event {
    font-size: 20px;
    width: 40px;
    text-align: center;
    height: 20px;
    line-height: 22px;
    margin: auto 0px;
    user-select: none;
    font-weight: 600;
}

.calendar-week-head-txt {
    font-size: 14px;
    height: 20px;
    line-height: 22px;
    margin: auto 0px;
}
</style>